#ifndef __TS_TRANSFER_HEADER_FILE_20060207__
#define __TS_TRANSFER_HEADER_FILE_20060207__

#ifdef __Win32__
#pragma warning(disable:4786)
#endif


#include <vector>
#include <map>
#include <string>
#include <list>
#include "OSHeaders.h"
#include "TCPSocket.h"
#include "OSMutex.h"
#include "TSProtocol.h"

#define VAL_MAX_CHANELS		10

using namespace std;

class Socket;
class UDPSocket;


class CTSTransfer
{
public:
	enum
	{
		DATA_TYPE_NONE = 0,
		DATA_TYPE_PEER = 1,
		DATA_TYPE_TRACKSERVER  = 2,
	};
	enum
	{
		TS_TYPE_TCP = 1,
		TS_TYPE_UDP = 2
	};
	struct RecvData {
		MSG_HEADER cHeader;
		char * pBuff;
	};
	
public:
	CTSTransfer();
	~CTSTransfer();

	Bool SetTcpSocket(Int32 inputSocket);

	OS_Error ReadData(UInt32 *pType, Int32 nTimeOut);
	vector<RecvData> * GetPeerRecvList() {return &m_PeerRecvBuffList;}

	void ClearRecvBuffer();
	Int32 SendData(const char* pBuf, const UInt32 nLen, UInt32 nType, UInt32 nCmdID);
	Int32 SendData(const struct iovec* iov, const UInt32 numIOvecs, UInt32 nType, UInt32 nCmdID);
	
	const char * GetLocalTCPSocketAddr();
	const char * GetRemoteTCPSocketAddr();

	Bool IsConnected();

	Bool	IsOverHTTP(){
		return m_OverHTTP;
	}

	void LogErrorInfo(UInt32 vFD,UInt32 vLevel, UInt32 vModule, Int32 vError, const char *vErrStr,UInt32 vLine = __LINE__);
private:

	
	UInt32					m_PeerDataType;
	UInt32					m_TrackNum;

	//for OVER HTTP
	Bool					m_OverHTTP;

	TCPSocket				*m_inputSocket;
	
	fd_set					m_fdSet;
	Int32					m_maxFds;
	Int32					m_FdCount;

	std::string					m_RemoteAddr;
	std::string					m_LocalAddr;

	//Receive Buffer
	char * m_pPeerRecvBuff;
	vector<RecvData> m_PeerRecvBuffList;
	//for Incomplete packet
	char * m_pPeerLeftBuff;
	UInt32 m_PeerLeftBuffLen;


protected:

	//get content length
	UInt32 GetContentLength(char *v_Str, UInt32 v_StrLen);

	OS_Error SendDataOverTCP(UInt32 iCmdID,
		UInt32 iPeerType,
		const struct iovec* iov, 
		const UInt32 numIOvecs,
		UInt32 &vSent,
		Bool IsBuffer);
	
	OSMutex	m_SendMutex;
};


inline Bool CTSTransfer::IsConnected()
{
	return m_inputSocket->IsConnected();
}



#endif
